#include "hj212.h"
#include <QDebug>

using namespace Moolink;

QString HJ212::getQN()
{
    QString QNStr = QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz");
    return QNStr;
}

QString HJ212::getDataTime()
{
    QString QNStr = QDateTime::currentDateTime().toString("yyyyMMddhhmmss");
    return QNStr;
}


QString HJ212::formatNumber(QString format, QVariant num)
{
    if(format.startsWith("N"))
    {
        QStringList formats=format.split(".");
        if(formats.size()>1)
        {
            int bits=formats.at(1).toInt();//转为数据长度为整形数formats.at(1).toInt();
            return QString::number(num.toDouble(),'f',bits);
        }
        else
            return QString::number(num.toInt());
    }

    return num.toString();

}


QString HJ212::getDataPacket(QString msgtext)
{
  QString PacketString="";
  QString sizeString="";
  QString crcString="";

  sizeString.sprintf("%04d",msgtext.size());
  crcString.sprintf("%04X",CRC16_Checkout(msgtext,msgtext.size()));

  PacketString+="##"+sizeString;
  PacketString+=msgtext;
  PacketString+=crcString;
  PacketString+="\r\n";

  return PacketString;
}

//int HJ212::getDataObject(QString recvmsg,HJ212_DATA &object,StationModel &station)
//{
//    int error=0;
//    int DataLength=0;
//    unsigned int CrcValue=0;
//    QString dataStr;

//    //检查数据包
//    //1.检查##头和\r\n尾
//        //(该功能已在TCP客户端底层实现，此处无需再判定,如需要TCP支持HJ212以外协议时再从TCP移回到此外)
//    //2.检查数据长度与校验值
//        if(recvmsg.size()>12)
//        {
//            QString lengthStr=recvmsg.mid(2,4);//取出数据长度字符数字串
//            if(IsNumber(lengthStr)) DataLength=lengthStr.toInt();//转为数据长度为整形数
//            if(DataLength==(recvmsg.size()-12))//检查数据长度是否符合
//            {
//                QString crcStr=recvmsg.mid(recvmsg.size()-6,4);//取出数据校验字串
//                if(IsHex(crcStr)) CrcValue=crcStr.toInt(nullptr,16);//转为数据长度为整形数
//                dataStr=recvmsg.mid(6,DataLength);//取出数据字符串
//                if(CrcValue!=CRC16_Checkout(dataStr,dataStr.size())) return 9;//校验检查错误
//            }
//            else return 100;//未知错误,包长度不符合
//        }else return 100;//未知错误,包长度过短

//     //3.分离CP与其他参数
//        QStringList dataPart=dataStr.split("CP=&&");
//     //4.取出常规参数
//        QStringList QNdataPart=dataPart.at(0).split(";");
//        if(QNdataPart.at(0).startsWith("QN=")) object.QN=QNdataPart.at(0).mid(3,QNdataPart.at(0).size()-3); else return 7;//QN错误=7
//        if(QNdataPart.at(1).startsWith("ST=")) object.ST=QNdataPart.at(1).mid(3,QNdataPart.at(1).size()-3).toInt(); else return 5;//ST错误=5
//        if(QNdataPart.at(2).startsWith("CN=")) object.CN=QNdataPart.at(2).mid(3,QNdataPart.at(2).size()-3).toInt(); else return 8;//CN错误=8
//        if(QNdataPart.at(3).startsWith("PW=")) object.PW=QNdataPart.at(3).mid(3,QNdataPart.at(3).size()-3); else return 3;//PW错误=3
//        if(QNdataPart.at(4).startsWith("MN=")) object.MN=QNdataPart.at(4).mid(3,QNdataPart.at(4).size()-3); else return 4;//MN错误=4
//        if(QNdataPart.at(5).startsWith("Flag=")) object.Flag=QNdataPart.at(5).mid(5,QNdataPart.at(5).size()-5).toInt(); else return 6;//Flag错误=6
//        if(QNdataPart.count()>6&&QNdataPart.at(6).startsWith("PNUM=")) object.PNUM=QNdataPart.at(6).mid(5,QNdataPart.at(6).size()-5).toInt();
//        if(QNdataPart.count()>7&&QNdataPart.at(7).startsWith("PNO=")) object.PNO=QNdataPart.at(7).mid(4,QNdataPart.at(7).size()-4).toInt();
//        //5.取出CP参数
//        if(dataPart.count()>1) object.CP=dataPart.at(1).mid(0,dataPart.at(1).size()-2);

//        //6.验证设备编号与密码
////        qDebug()<<"MN:"<<object.MN.size()<<"size"<<station.getMN().size()<<"\r\n";
////        qDebug()<<"MN:"<<object.MN<<QString::compare(station.getMN(),object.MN)<<station.getMN()<<"\r\n";
//        if(object.MN.size()!=station.getMN().size()||0!=QString::compare(station.getMN(),object.MN)) return 4;//MN错误=4

//        if(object.PW.size()!=station.getPW().size()||0!=QString::compare(station.getPW(),object.PW)) return 3;//PW错误=3

//return error;

//}


int HJ212::getDataObject(QString recvmsg,HJ212_DATA &object,Host &host)
{
    int error=0;
    int DataLength=0;
    unsigned int CrcValue=0;
    QString dataStr;

    //检查数据包
    //1.检查##头和\r\n尾
        //(该功能已在TCP客户端底层实现，此处无需再判定,如需要TCP支持HJ212以外协议时再从TCP移回到此外)
    //2.检查数据长度与校验值
        if(recvmsg.size()>12)
        {
            QString lengthStr=recvmsg.mid(2,4);//取出数据长度字符数字串
            if(IsNumber(lengthStr)) DataLength=lengthStr.toInt();//转为数据长度为整形数
            if(DataLength==(recvmsg.size()-12))//检查数据长度是否符合
            {
                QString crcStr=recvmsg.mid(recvmsg.size()-6,4);//取出数据校验字串
                if(IsHex(crcStr)) CrcValue=crcStr.toInt(nullptr,16);//转为数据长度为整形数
                dataStr=recvmsg.mid(6,DataLength);//取出数据字符串
                if(CrcValue!=CRC16_Checkout(dataStr,dataStr.size())) return 9;//校验检查错误
            }
            else return 101;//未知错误,包长度不符合
        }else return 102;//未知错误,包长度过短

     //3.分离CP与其他参数
        QStringList dataPart=dataStr.split("CP=&&");
     //4.取出常规参数
        QStringList QNdataPart=dataPart.at(0).split(";");
        if(QNdataPart.at(0).startsWith("QN=")) object.QN=QNdataPart.at(0).mid(3,QNdataPart.at(0).size()-3); else return 7;//QN错误=7
        if(QNdataPart.at(1).startsWith("ST=")) object.ST=QNdataPart.at(1).mid(3,QNdataPart.at(1).size()-3).toInt(); else return 5;//ST错误=5
        if(QNdataPart.at(2).startsWith("CN=")) object.CN=QNdataPart.at(2).mid(3,QNdataPart.at(2).size()-3).toInt(); else return 8;//CN错误=8
        if(QNdataPart.at(3).startsWith("PW=")) object.PW=QNdataPart.at(3).mid(3,QNdataPart.at(3).size()-3); else return 3;//PW错误=3
        if(QNdataPart.at(4).startsWith("MN=")) object.MN=QNdataPart.at(4).mid(3,QNdataPart.at(4).size()-3); else return 4;//MN错误=4
        if(QNdataPart.at(5).startsWith("Flag=")) object.Flag=QNdataPart.at(5).mid(5,QNdataPart.at(5).size()-5).toInt(); else return 6;//Flag错误=6
        if(QNdataPart.count()>6&&QNdataPart.at(6).startsWith("PNUM=")) object.PNUM=QNdataPart.at(6).mid(5,QNdataPart.at(6).size()-5).toInt();
        if(QNdataPart.count()>7&&QNdataPart.at(7).startsWith("PNO=")) object.PNO=QNdataPart.at(7).mid(4,QNdataPart.at(7).size()-4).toInt();
        //5.取出CP参数
        if(dataPart.count()>1) object.CP17=dataPart.at(1).mid(0,dataPart.at(1).size()-2);

        //6.验证设备编号与密码
        if(object.MN.size()!=host.stationMN.size()||0!=QString::compare(host.stationMN,object.MN)) return 4;//MN错误=4
        if(object.PW.size()!=host.stationPW.size()||0!=QString::compare(host.stationPW,object.PW)) return 3;//PW错误=3

return error;


}






bool HJ212::recvCN1000(QString &qstrSrc,StationModel &object)
{

    bool bret = true;
    QStringList dataPart=qstrSrc.split(";");
    if(dataPart.at(0).startsWith("OverTime=")) object.setOverTime(dataPart.at(0).mid(9,dataPart.at(0).size()-9));
    if(dataPart.at(1).startsWith("ReCount=")) object.setReCount(dataPart.at(1).mid(8,dataPart.at(1).size()-8));
    return bret;
}

QString HJ212::recvCN1011(QString &qstrSrc)
{
    QString polid;
    if(qstrSrc.startsWith("PolId=")) polid=qstrSrc.mid(5,qstrSrc.size()-6);

    return polid;
}

bool HJ212::recvCN1012(QString &qstrSrc,Device &object)
{
    bool bret = true;
    QStringList dataPart=qstrSrc.split(";");

    if(dataPart.size()>2)
    {
        if(dataPart.at(0).startsWith("PolId=")) object.name=(dataPart.at(0).mid(5,dataPart.at(0).size()-5));
        if(dataPart.at(1).startsWith("SystemTime=")) object.SystemTime=(dataPart.at(1).mid(11,dataPart.at(1).size()-11));
    }
    else if(dataPart.size()==1)
    {
        if(dataPart.at(0).startsWith("SystemTime=")) object.SystemTime=(dataPart.at(0).mid(11,dataPart.at(0).size()-11));
    }


    return bret;
}

QString HJ212::recvCN1062(QString &qstrSrc)
{
    QString RtdInterval;
    if(qstrSrc.startsWith("RtdInterval=")) RtdInterval=qstrSrc.mid(12,qstrSrc.size()-12);

    return RtdInterval;
}


QString HJ212::GetCpValueByKey(QString &qstrSrc,QString key)
{

    QStringList dataPart=qstrSrc.split(";");
    for(int i=0;i<dataPart.size();i++)
    {
        if(dataPart.at(i).startsWith(key+"=")) return (dataPart.at(i).mid(key.size()+1,dataPart.at(i).size()-(key.size()+1)));

    }

    return "";
}

//QString HJ212::ResponseData(HJ212_DATA &object,QString cpStr,int Flag)
//{
//    cpStr=cpStr.toLatin1();
//    //return getDataPacket("QN="+object.QN+";ST="+object.ST+";CN="+object.CN+";PW="+object.PW+";MN="+object.MN+";Flag="+object.Flag+";CP=&&"+cpStr+"&&");
//    return getDataPacket("QN="+object.QN+";ST=32;CN="+QString::number(object.CN,10)+";PW="+object.PW+";MN="+object.MN+";Flag="+QString::number(Flag,10)+";CP=&&"+cpStr+"&&");
//}

QString HJ212::ResponseData(HJ212_DATA &object,QString cpStr)
{
    cpStr=cpStr.toLatin1();
    //return getDataPacket("QN="+object.QN+";ST="+object.ST+";CN="+object.CN+";PW="+object.PW+";MN="+object.MN+";Flag="+object.Flag+";CP=&&"+cpStr+"&&");
    return getDataPacket("QN="+object.QN+";ST=32;CN="+QString::number(object.CN,10)+";PW="+object.PW+";MN="+object.MN+";Flag="+QString::number(object.Flag,10)+";CP=&&"+cpStr+"&&");
}

QString HJ212::ResponseData(HJ212_DATA &object)
{
    QString cpStr;
    if(0==(object.Flag&0xFC))
        cpStr=object.CP05.toLatin1();
    else
        cpStr=object.CP17.toLatin1();
    //return getDataPacket("QN="+object.QN+";ST="+object.ST+";CN="+object.CN+";PW="+object.PW+";MN="+object.MN+";Flag="+object.Flag+";CP=&&"+cpStr+"&&");
    return getDataPacket("QN="+object.QN+";ST=32;CN="+QString::number(object.CN,10)+";PW="+object.PW+";MN="+object.MN+";Flag="+QString::number(object.Flag,10)+";CP=&&"+cpStr+"&&");
}


QString HJ212::ReqReponse(HJ212_DATA &object,int QnRtn)
{
    //return getDataPacket("QN="+object.QN+";ST="+object.ST+";CN="+object.CN+";PW="+object.PW+";MN="+object.MN+";Flag="+object.Flag+";CP=&&QnRtn=1&&");
    return getDataPacket("QN="+object.QN+";ST=91;CN=9011;PW="+object.PW+";MN="+object.MN+";Flag="+QString::number(object.Flag,10)+";CP=&&QnRtn="+QString::number(QnRtn,10)+"&&");
}
QString HJ212::ReqResult(HJ212_DATA &object,int ExeRtn)
{
    //return getDataPacket("QN="+object.QN+";ST="+object.ST+";CN="+object.CN+";PW="+object.PW+";MN="+object.MN+";Flag="+object.Flag+";CP=&&ExeRtn=1&&");
    return getDataPacket("QN="+object.QN+";ST=91;CN=9012;PW="+object.PW+";MN="+object.MN+";Flag="+QString::number(object.Flag,10)+";CP=&&ExeRtn="+QString::number(ExeRtn,10)+"&&");
}


unsigned int HJ212::CRC16_Checkout (const QString Str, unsigned int usDataLen )
{
int i,j,crc_reg,check;

QByteArray Byte=Str.toUtf8();


crc_reg = 0xFFFF;
for(i=0;i<usDataLen;i++)
{
crc_reg = (crc_reg>>8) ^ int(Byte.at(i));
    for(j=0;j<8;j++)
{
  check = crc_reg & 0x0001;
  crc_reg >>= 1;
        if(check==0x0001)
{
   crc_reg ^= 0xA001;
  }
 }
}
return crc_reg;
}

bool HJ212::IsNumber(QString &qstrSrc)
{
    QByteArray ba = qstrSrc.toLatin1();
    const char *s = ba.data();
    bool bret = true;
    while(*s)
    {
        if(*s>='0' && *s<='9')
        {

        }
        else
        {
            bret = false;
            break;
        }
        s++;
    }
    return bret;
}

bool HJ212::IsHex(QString &qstrSrc)
{
    QByteArray ba = qstrSrc.toLatin1();
    const char *s = ba.data();
    bool bret = true;
    while(*s)
    {
        if((*s>='A' && *s<='F') || (*s>='a' && *s<='f') || (*s>='0' && *s<='9'))
        {

        }
        else
        {
            bret = false;
            break;
        }
        s++;
    }
    return bret;
}

